<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>Irrlicht 3D Engine: Tutorial 14: Win32 Window</title>

<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
  $(document).ready(function() { searchBox.OnSelectItem(0); });
</script>

</head>
<body>
<div id="top"><!-- do not remove this div! -->


<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  
  <td id="projectlogo"><img alt="Logo" src="irrlichtlogo.png"/></td>
  
  
  <td style="padding-left: 0.5em;">
   <div id="projectname">Irrlicht 3D Engine
   
   </div>
   
  </td>
  
  
  
   
   <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
</td>
   
  
 </tr>
 </tbody>
</table>
</div>

<!-- Generated by Doxygen 1.7.5.1 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="dynsections.js"></script>
</div>
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
  initNavTree('example014.html','');
</script>
<div id="doc-content">
<div class="header">
  <div class="headertitle">
<div class="title">Tutorial 14: Win32 Window </div>  </div>
</div>
<div class="contents">
<div class="textblock"><div class="image">
<img src="014shot.jpg" alt="014shot.jpg"/>
</div>
 <p>This example only runs under MS Windows and demonstrates that Irrlicht can render inside a win32 window. MFC and .NET Windows.Forms windows are possible, too.</p>
<p>In the beginning, we create a windows window using the windows API. I'm not going to explain this code, because it is windows specific. See the MSDN or a windows book for details. </p>
<div class="fragment"><pre class="fragment"><span class="preprocessor">#include &lt;<a class="code" href="irrlicht_8h.html" title="Main header file of the irrlicht, the only file needed to include.">irrlicht.h</a>&gt;</span>
<span class="preprocessor">#ifndef _IRR_WINDOWS_</span>
<span class="preprocessor"></span><span class="preprocessor">#error Windows only example</span>
<span class="preprocessor"></span><span class="preprocessor">#else</span>
<span class="preprocessor"></span><span class="preprocessor">#include &lt;windows.h&gt;</span> <span class="comment">// this example only runs with windows</span>
<span class="preprocessor">#include &lt;iostream&gt;</span>
<span class="preprocessor">#include &quot;<a class="code" href="driver_choice_8h.html">driverChoice.h</a>&quot;</span>

<span class="keyword">using namespace </span>irr;

<span class="preprocessor">#pragma comment(lib, &quot;irrlicht.lib&quot;)</span>
<span class="preprocessor"></span>
HWND hOKButton;
HWND hWnd;

<span class="keyword">static</span> LRESULT CALLBACK CustomWndProc(HWND hWnd, UINT message,
        WPARAM wParam, LPARAM lParam)
{
    <span class="keywordflow">switch</span> (message)
    {
    <span class="keywordflow">case</span> WM_COMMAND:
        {
            HWND hwndCtl = (HWND)lParam;
            <span class="keywordtype">int</span> code = HIWORD(wParam);

            <span class="keywordflow">if</span> (hwndCtl == hOKButton)
            {
                DestroyWindow(hWnd);
                PostQuitMessage(0);
                <span class="keywordflow">return</span> 0;
            }
        }
        <span class="keywordflow">break</span>;
    <span class="keywordflow">case</span> WM_DESTROY:
        PostQuitMessage(0);
        <span class="keywordflow">return</span> 0;

    }

    <span class="keywordflow">return</span> DefWindowProc(hWnd, message, wParam, lParam);
}
</pre></div><p>Now ask for the driver and create the Windows specific window. </p>
<div class="fragment"><pre class="fragment"><span class="keywordtype">int</span> main()
{
    <span class="comment">// ask user for driver</span>
    <a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0" title="An enum for all types of drivers the Irrlicht Engine supports.">video::E_DRIVER_TYPE</a> driverType=driverChoiceConsole();
    <span class="keywordflow">if</span> (driverType==<a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0ae685cada50f8c100403134d932d0414c" title="No driver, just for counting the elements.">video::EDT_COUNT</a>)
        <span class="keywordflow">return</span> 1;

    printf(<span class="stringliteral">&quot;Select the render window (some dead window may exist too):\n&quot;</span>\
        <span class="stringliteral">&quot; (a) Window with button (via CreationParam)\n&quot;</span>\
        <span class="stringliteral">&quot; (b) Window with button (via beginScene)\n&quot;</span>\
        <span class="stringliteral">&quot; (c) Own Irrlicht window (default behavior)\n&quot;</span>\
        <span class="stringliteral">&quot; (otherKey) exit\n\n&quot;</span>);

    <span class="keywordtype">char</span> key;
    std::cin &gt;&gt; key;
    <span class="keywordflow">if</span> (key != <span class="charliteral">&#39;a&#39;</span> &amp;&amp; key != <span class="charliteral">&#39;b&#39;</span> &amp;&amp; key != <span class="charliteral">&#39;c&#39;</span>)
        <span class="keywordflow">return</span> 1;

    HINSTANCE hInstance = 0;
    <span class="comment">// create dialog</span>

    <span class="keyword">const</span> <span class="keywordtype">char</span>* Win32ClassName = <span class="stringliteral">&quot;CIrrlichtWindowsTestDialog&quot;</span>;

    WNDCLASSEX wcex;
    wcex.cbSize         = <span class="keyword">sizeof</span>(WNDCLASSEX);
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = (WNDPROC)CustomWndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = DLGWINDOWEXTRA;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = NULL;
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW);
    wcex.lpszMenuName   = 0;
    wcex.lpszClassName  = Win32ClassName;
    wcex.hIconSm        = 0;

    RegisterClassEx(&amp;wcex);

    DWORD style = WS_SYSMENU | WS_BORDER | WS_CAPTION |
        WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SIZEBOX;

    <span class="keywordtype">int</span> windowWidth = 440;
    <span class="keywordtype">int</span> windowHeight = 380;

    hWnd = CreateWindow( Win32ClassName, <span class="stringliteral">&quot;Irrlicht Win32 window example&quot;</span>,
        style, 100, 100, windowWidth, windowHeight,
        NULL, NULL, hInstance, NULL);

    RECT clientRect;
    GetClientRect(hWnd, &amp;clientRect);
    windowWidth = clientRect.right;
    windowHeight = clientRect.bottom;

    <span class="comment">// create ok button</span>

    hOKButton = CreateWindow(<span class="stringliteral">&quot;BUTTON&quot;</span>, <span class="stringliteral">&quot;OK - Close&quot;</span>, WS_CHILD | WS_VISIBLE | BS_TEXT,
        windowWidth - 160, windowHeight - 40, 150, 30, hWnd, NULL, hInstance, NULL);

    <span class="comment">// create some text</span>

    CreateWindow(<span class="stringliteral">&quot;STATIC&quot;</span>, <span class="stringliteral">&quot;This is Irrlicht running inside a standard Win32 window.\n&quot;</span>\
        <span class="stringliteral">&quot;Also mixing with MFC and .NET Windows.Forms is possible.&quot;</span>,
        WS_CHILD | WS_VISIBLE, 20, 20, 400, 40, hWnd, NULL, hInstance, NULL);

    <span class="comment">// create window to put irrlicht in</span>

    HWND hIrrlichtWindow = CreateWindow(<span class="stringliteral">&quot;BUTTON&quot;</span>, <span class="stringliteral">&quot;&quot;</span>,
            WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
            50, 80, 320, 220, hWnd, NULL, hInstance, NULL);
    video::SExposedVideoData videodata((key==<span class="charliteral">&#39;b&#39;</span>)?hIrrlichtWindow:0);
</pre></div><p>So now that we have some window, we can create an Irrlicht device inside of it. We use Irrlicht createEx() function for this. We only need the handle (HWND) to that window, set it as windowsID parameter and start up the engine as usual. That's it. </p>
<div class="fragment"><pre class="fragment">    <span class="comment">// create irrlicht device in the button window</span>

    <a class="code" href="structirr_1_1_s_irrlicht_creation_parameters.html" title="Structure for holding Irrlicht Device creation parameters.">irr::SIrrlichtCreationParameters</a> param;
    param.<a class="code" href="structirr_1_1_s_irrlicht_creation_parameters.html#a1ea2f50c3b3a8eed6602a1a86e1cdf82" title="Type of video driver used to render graphics.">DriverType</a> = driverType;
    <span class="keywordflow">if</span> (key==<span class="charliteral">&#39;a&#39;</span>)
        param.<a class="code" href="structirr_1_1_s_irrlicht_creation_parameters.html#af287810d910a23f8f7db98cef87b6eae" title="Window Id.">WindowId</a> = <span class="keyword">reinterpret_cast&lt;</span><span class="keywordtype">void</span>*<span class="keyword">&gt;</span>(hIrrlichtWindow);

    <a class="code" href="classirr_1_1_irrlicht_device.html" title="The Irrlicht device. You can create it with createDevice() or createDeviceEx().">irr::IrrlichtDevice</a>* device = <a class="code" href="namespaceirr.html#ac83a30d674204dcb94d70f849e9b4a62" title="Creates an Irrlicht device with the option to specify advanced parameters.">irr::createDeviceEx</a>(param);
    <span class="keywordflow">if</span> (!device)
        <span class="keywordflow">return</span> 1;

    <span class="comment">// setup a simple 3d scene</span>

    <a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html" title="The Scene Manager manages scene nodes, mesh recources, cameras and all the other stuff.">irr::scene::ISceneManager</a>* smgr = device-&gt;<a class="code" href="classirr_1_1_irrlicht_device.html#a891b503ff4d5041296d88f23f97d7b3d" title="Provides access to the scene manager.">getSceneManager</a>();
    video::IVideoDriver* driver = device-&gt;<a class="code" href="classirr_1_1_irrlicht_device.html#ada90707ba5c645d47e000e4e0f87c4c4" title="Provides access to the video driver for drawing 3d and 2d geometry.">getVideoDriver</a>();

    <span class="keywordflow">if</span> (driverType==<a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0a2715182a79f1cb8e2826fd68a8150a53" title="OpenGL device, available on most platforms.">video::EDT_OPENGL</a>)
    {
        HDC HDc=GetDC(hIrrlichtWindow);
        PIXELFORMATDESCRIPTOR pfd={0};
        pfd.nSize=<span class="keyword">sizeof</span>(PIXELFORMATDESCRIPTOR);
        <span class="keywordtype">int</span> pf = GetPixelFormat(HDc);
        DescribePixelFormat(HDc, pf, <span class="keyword">sizeof</span>(PIXELFORMATDESCRIPTOR), &amp;pfd);
        pfd.dwFlags |= PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
        pfd.cDepthBits=16;
        pf = ChoosePixelFormat(HDc, &amp;pfd);
        SetPixelFormat(HDc, pf, &amp;pfd);
        videodata.OpenGLWin32.HDc = HDc;
        videodata.OpenGLWin32.HRc=wglCreateContext(HDc);
        wglShareLists((HGLRC)driver-&gt;getExposedVideoData().OpenGLWin32.HRc, (HGLRC)videodata.OpenGLWin32.HRc);
    }
    scene::ICameraSceneNode* cam = smgr-&gt;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#afc3733849319078d5d22d94f58c7d1f2" title="Adds a camera scene node to the scene graph and sets it as active camera.">addCameraSceneNode</a>();
    cam-&gt;setTarget(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,0,0));

    scene::ISceneNodeAnimator* anim =
        smgr-&gt;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a2e49ff49bc9e88e8ecf3d681354e1ab6" title="Creates a fly circle animator, which lets the attached scene node fly around a center.">createFlyCircleAnimator</a>(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,15,0), 30.0f);
    cam-&gt;addAnimator(anim);
    anim-&gt;drop();

    scene::ISceneNode* cube = smgr-&gt;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a23d1328c68b1585f613108f386fabc1c" title="Adds a cube scene node.">addCubeSceneNode</a>(20);

    cube-&gt;setMaterialTexture(0, driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/wall.bmp&quot;</span>));
    cube-&gt;setMaterialTexture(1, driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/water.jpg&quot;</span>));
    cube-&gt;setMaterialFlag( <a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3acea597a2692b8415486a464a7f954d34" title="Will this material be lighted? Default: true.">video::EMF_LIGHTING</a>, <span class="keyword">false</span> );
    cube-&gt;setMaterialType( <a class="code" href="namespaceirr_1_1video.html#ac8e9b6c66f7cebabd1a6d30cbc5430f1ad8574343353ed8ade6e78bc04d64b6ae" title="A reflecting material with an optional non reflecting texture layer.">video::EMT_REFLECTION_2_LAYER</a> );

    smgr-&gt;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a2b08b9f20ec62faeffc02b9fed9fd683" title="Adds a skybox scene node to the scene graph.">addSkyBoxSceneNode</a>(
    driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/irrlicht2_up.jpg&quot;</span>),
    driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/irrlicht2_dn.jpg&quot;</span>),
    driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/irrlicht2_lf.jpg&quot;</span>),
    driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/irrlicht2_rt.jpg&quot;</span>),
    driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/irrlicht2_ft.jpg&quot;</span>),
    driver-&gt;getTexture(<span class="stringliteral">&quot;../../media/irrlicht2_bk.jpg&quot;</span>));

    <span class="comment">// show and execute dialog</span>

    ShowWindow(hWnd , SW_SHOW);
    UpdateWindow(hWnd);

    <span class="comment">// do message queue</span>
</pre></div><p>Now the only thing missing is the drawing loop using IrrlichtDevice::run(). We do this as usual. But instead of this, there is another possibility: You can also simply use your own message loop using GetMessage, DispatchMessage and whatever. Calling Device-&gt;run() will cause Irrlicht to dispatch messages internally too. You need not call Device-&gt;run() if you want to do your own message dispatching loop, but Irrlicht will not be able to fetch user input then and you have to do it on your own using the window messages, DirectInput, or whatever. </p>
<div class="fragment"><pre class="fragment">    <span class="keywordflow">while</span> (device-&gt;<a class="code" href="classirr_1_1_irrlicht_device.html#a0489f8151dc43f6f41503ffb5a160b35" title="Runs the device.">run</a>())
    {
        driver-&gt;beginScene(<span class="keyword">true</span>, <span class="keyword">true</span>, 0, videodata);
        smgr-&gt;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a04240262904667c821bd9de5e5fd9b02" title="Draws all the scene nodes.">drawAll</a>();
        driver-&gt;endScene();
    }
</pre></div><p>The alternative, own message dispatching loop without Device-&gt;run() would look like this: </p>
<div class="fragment"><pre class="fragment"></pre></div><p> MSG msg; while (true) { if (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg);</p>
<p>if (msg.message == WM_QUIT) break; }</p>
<p>advance virtual time device-&gt;getTimer()-&gt;tick();</p>
<p>draw engine picture driver-&gt;beginScene(true, true, 0, (key=='c')?hIrrlichtWindow:0); smgr-&gt;drawAll(); driver-&gt;endScene(); } </p>
<div class="fragment"><pre class="fragment">    device-&gt;<a class="code" href="classirr_1_1_irrlicht_device.html#a08c97937e0f60f98d443b397a7c60e18" title="Notifies the device that it should close itself.">closeDevice</a>();
    device-&gt;<a class="code" href="classirr_1_1_i_reference_counted.html#afb169a857e0d2cdb96b8821cb9bff17a" title="Drops the object. Decrements the reference counter by one.">drop</a>();

    <span class="keywordflow">return</span> 0;
}
<span class="preprocessor">#endif // if windows</span>
</pre></div><p>That's it, Irrlicht now runs in your own windows window. </p>
</div></div>
</div>
  <div id="nav-path" class="navpath">
    <ul>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark">&#160;</span>Friends</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark">&#160;</span>Defines</a></div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>


    <li class="footer">
<a href="http://irrlicht.sourceforge.net" target="_blank">Irrlicht 
Engine</a> Documentation &copy; 2003-2012 by Nikolaus Gebhardt. Generated on Sat Jul 9 2016 18:18:26 for Irrlicht 3D Engine by
<a href="http://www.doxygen.org/index.html" target="_blank">Doxygen</a> 1.7.5.1 </li>
   </ul>
 </div>


</body>
</html>
